import Vue from 'vue'
import VueResource from 'vue-resource'
import { MessageBox } from 'element-ui';
import { Loading } from 'element-ui';

import ext from './extend'

Vue.use(VueResource)

const apiUrl = '/api/';


/**
 * vue 插件中的 this.$api 对象
 */
const api = {
  /**
   * 返回一个Promise，后续使用then增加成功与失败回调
   * opt为 vue-resource 的post方法参数，增加以下属性：
   * noAlert：为true时不弹出失败提示，只针对业务失败
   * 如果需要在 before 与 after 函数中使用 this, 需要传入 context=this
   */
  async call ({service, body, opt, load}){
    let options = {
      timeout: 30000,
      ...opt
    }
    let response;
    let loadingInstance;
    if (load && load.context && load.name){
      load.context[load.name] = true;
    }else{
      loadingInstance = Loading.service({
        body: true,
        fullscreen: true,
        lock: true,
        text: '加载中...'
      });
    }
    try{
       response = await Vue.http.post(apiUrl + service, body, options);
    }catch(e){
      response = e;
      await MessageBox.alert(`status:${response.status}  -  text:${response.statusText}`, '请求失败：', {
        type: 'error',
        confirmButtonText: '确定'
      });
      throw e;
    }finally{
      if (load && load.context && load.name){
        load.context[load.name] = false;
      }else{
        loadingInstance && loadingInstance.close()    //判断是否需要关闭提示框
      }
      console.log(`${service} ===>  status:${response.status}`); 
    }
    let resBody = response.body;
    let head = resBody.head || {};
    console.log(`head ----> code : ${head.code}, msg: ${head.msg}`);
    if (head.code === '0'){
      return resBody.body;
    } else {
      await MessageBox.alert(`${head.code} - ${head.msg} <br/> ${resBody.stack}`, '请求失败：', {
        type: 'error',
        confirmButtonText: '确定'
      });
      let e = new Error();
      e.code = head.code;
      e.msg = head.msg;
      throw e;
    }
  }
}

/**
 * 装载 vue 插件
 */
function install(Vue){  
    if (install.installed) {
        return;
    }

    Vue.prototype.$api = api
}

/* istanbul ignore if */
if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue);
};

export default {
  install, api
}